using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.ServiceModel;
using Needle.Bus.Transport.Impl.LoopBack;
using Needle.Bus.Transport.Impl.WCF;
using Needle.Bus.Transport;
using System.Threading;
using System.Diagnostics;

namespace Needle.Bus.Tests.Transport
{

    public class EndPoint<T> : IEndPoint<T>
    {
        private readonly object _thisLock = new object();

        public EndPoint(string topic)
        {
            _Topic = topic;
            _ReceivedMessages = new List<T>();
        }

        #region IEndPoint<T> Members

        private readonly string _Topic;
        public string Topic
        {
            get { return _Topic; }
        }

        public int ReceivedCount
        {
            get
            {
                lock (_thisLock)
                { return _ReceivedMessages.Count; }
            }
        }

        public void Receive(T message)
        {
            lock (_thisLock)
            { _ReceivedMessages.Add(message); }
        }

        private List<T> _ReceivedMessages;
        public T[] ReceivedMessages
        {
            get
            {
                lock (_thisLock)
                { return _ReceivedMessages.ToArray(); }
            }
        }

        #endregion

        #region IExtension<ITransport> Members

        void IExtension<ITransport>.Attach(ITransport owner)
        {
            lock (_thisLock)
            { _AttachCalls++; }
        }

        void IExtension<ITransport>.Detach(ITransport owner)
        {
            lock (_thisLock)
            { _DetachCalls++; }
        }

        #endregion

        private int _AttachCalls;
        public int AttachCalls
        {
            get
            {
                lock (_thisLock)
                { return _AttachCalls; }
            }
        }

        private int _DetachCalls;
        public int DetachCalls
        {
            get
            {
                lock (_thisLock)
                { return _DetachCalls; }
            }
        }

        public TimeSpan WaitForMessages(int messageCount,TimeSpan maxDelay)
        {
            Stopwatch watch = Stopwatch.StartNew();
            while (ReceivedCount < messageCount)
            {
                if (watch.Elapsed >= maxDelay)
                    break;
                Thread.Sleep(1);
            }
            watch.Stop();
            return watch.Elapsed;
        }
   
    }
}
